using System;
using System.IO;

namespace Game.Lib
{
    public class UUID : Serializable
    {
        #region Constants

        public readonly static UUID NULL_KEY = new UUID("00000000-0000-0000-0000-000000000000");
        
        #endregion
        
        #region Fields
        
        public Guid Data;
        
        #endregion
        
        #region Constructors
        
        public UUID()
        {
            Data = Guid.NewGuid();
        }
        
        public UUID(string a)
        {
            Data = new Guid(a);
        }
        
        #endregion
        
        #region Methods
        
        public override int GetHashCode()
        {
            return Data.GetHashCode();
        }
        
        public override string ToString()
        {
            return Data.ToString();
        }

        public override bool Equals(object obj)
        {
            if (obj is UUID)
            {
                return this == (UUID)obj;
            }
            else if (obj is Guid)
            {
                return Data == (Guid)obj;
            }
            else return false;
        }

        #endregion

        #region Operators

        public static bool operator ==(UUID a, UUID b)
        {
            return a.Data == b.Data;
        }

        public static bool operator !=(UUID a, UUID b)
        {
            return a.Data != b.Data;
        }

        #endregion

        #region Serializable

        public void FromBytes(byte[] data, int pos)
        {
            byte[] buf = new byte[16];
            Buffer.BlockCopy(data, pos, buf, 0, 16);
            Data = new Guid(buf);
        }

        public byte[] ToBytes()
        {
            return Data.ToByteArray();
        }

        public void Serialize(Stream s)
        {
            if(!s.CanWrite) throw new ArgumentException("Stream must be writable to support serialization");
            s.Write(Data.ToByteArray(), 0, 16);
        }

        public void Deserialize(Stream s)
        {
            if(!s.CanRead) throw new ArgumentException("Stream must be readable to support deserialization");
            byte[] buf = new byte[16];
            if(s.Read(buf, 0, 16) != 16) throw new EndOfStreamException();
            Data = new Guid(buf);
        }

        #endregion
    }
}